#ifndef frm_control_TString_H
#define frm_control_TString_H

#include "frm_control_TPanel.h"
#include "frm_TFont.h"

namespace frm { namespace control {

///////////////////////////////////////////////////////////////////////////////
       
struct TString : public TPanel
{
  struct TStyle : public frm::TStyle
  {
    svl_Type(frm::TStyle)
    
    struct TState : public TPanel::TStyle 
    { 
      TFont Font; 
      //
      virtual svl::TInfoParam AddInfoTo(svl::TInfoParam Info);
    };
    //
    TState Normal,Focused,Selected; 
    //
    TStyle();
    //
    void CalcFontAll();
    void SetFontDefault();
    void SetFontParent(TStyle &Parent);
    //
    virtual void SetFromParent(frm::TStyle *Parent);
    //
    virtual svl::TInfoParam AddInfoTo(svl::TInfoParam Info);
    //
    static TStyle &GetDefault();
  };



/**********************
  ////////////////////////////////////////////////////////
  struct TEventsList; struct TEvents : public svl::TEvents
  {
    ///////////////////////////////////////////
    struct TParam : public svl::TEvents::TParam
    {
      TString &Sender;
      //
      TParam(TEventsList &eventsList) : svl::TEvents::TParam(eventsList),Sender(eventsList.Sender) {}
    };

    enum EChangeValue
    {
      EChangeValue_Set,
      EChangeValue_Update,
      //EChangeValue_Keyboard
    };
    struct TChangeValue : public TParam
    {
      EChangeValue  eChangeValue;
      svl::TString  OldVal;
      svl::TString &NewVal;
      //
      TChangeValue(TEventsList &eventsList,EChangeValue eChangeValue,svl::TString oldVal,svl::TString &newVal)
      :TParam(eventsList),OldVal(oldVal),NewVal(newVal) { this->eChangeValue = eChangeValue; }
    };
    virtual void TEvents_BeforeChangeValue(TChangeValue &Param) { TEvents *P = (TEvents*)Param.GetPrev(); if (P) { P->TEvents_BeforeChangeValue(Param);} }
    virtual void TEvents_AfterChangeValue (TChangeValue &Param) { TEvents *P = (TEvents*)Param.GetPrev(); if (P) { P->TEvents_AfterChangeValue (Param);} }
  };
  ////////////////////////////////////////////
  struct TEventsList : public svl::TEventsList
  {
    TString &Sender;
    //
    TEventsList(TString &sender) : Sender(sender),svl::TEventsList(Default()) {}
    //
    void Link  (TEvents &V) { svl::TEventsList::Link  (V);}
    void Unlink(TEvents &V) { svl::TEventsList::Unlink(V);}

  private:
    void BeforeChangeValue(TEvents::TChangeValue &Param) { Get().TEvents_BeforeChangeValue(Param);}
    void AfterChangeValue (TEvents::TChangeValue &Param) { Get().TEvents_BeforeChangeValue(Param);}
    //
    TEvents &Get() { return (TEvents&)svl::TEventsList::GetBot();}
    static TEvents &Default() { static TEvents E; return E;}
    friend TString;
  }
  Events;
*********************************/

  //
  TString(TWindow &Window);
 ~TString();
  svl_Type(TPanel)
  //
  TString &SetStyle(TStyle &V);
  //
  svl::TString    GetValue();
  virtual void    SetValue(svl::TString V) {    SetValueE(V/*,TEvents::EChangeValue_Set*/);}
  virtual bool UpdateValue(svl::TString V) { UpdateValueE(V/*,TEvents::EChangeValue_Update*/); return true;}
  void       ReupdateValue();
  //
  int XSizeToPos(int XSize);
  int PosToXSize(int Pos);
  //
  virtual bool DeleteSymbolInPos(int Pos);

protected:
  virtual TComponent *TComponent_New();
  //
  virtual void TComponent_Paint(TPaint &Paint,int NPaintStack);
  virtual void TComponent_Mouse(TMouse  Mouse);
  //
  virtual void TComponent_KeyboardKey (grf::TKeyboardKey  &KeyboardKey);
  virtual void TComponent_KeyboardChar(grf::TKeyboardChar &KeyboardChar);
  //
  virtual TComponent *TComponent_SplitInSize(TMergeSplit &MS,int InSize);
  virtual TComponent *TComponent_SplitInPos (TMergeSplit &MS,int InPos);
  virtual bool        TComponent_MergeFrom  (TMergeSplit &MS,TComponent *InCFrom);

protected:
  virtual bool TComponent_FocusEnable() { return true;}
  virtual void TComponent_FocusEnter();
  virtual void TComponent_FocusExit ();

  virtual bool TComponent_SelectEnable() { return true; }
  virtual void TComponent_SelectEnter();
  virtual void TComponent_SelectExit();
  //
  virtual bool TComponent_CaretIsBegin();
  virtual bool TComponent_CaretIsEnd  ();
  //
  virtual void TComponent_SetCaretToBegin();
  virtual void TComponent_SetCaretToEnd  ();
  //
  virtual int TComponent_GetCaretMaxPos();
  //
  virtual void TComponent_SetCaretByX  (TGeometryRect &GRect,int XClient);
  virtual void TComponent_SetCaretByPos(TGeometryRect &GRect,int Pos);
  //
  virtual void TComponent_ScrollToVisible(TGeometryRect &GRect);
  //
  virtual void TComponent_AfterChangeWidth(int OldVal,int NewVal);
  virtual void TComponent_ChangeScale(double Scale);
  //
  virtual void TComponent_InheritStyleFrom(TTableOfStyles &ParentStyles);

private:
  void    SetValueE(svl::TString V/*,TEvents::EChangeValue eChangeValue*/);
  void UpdateValueE(svl::TString V/*,TEvents::EChangeValue eChangeValue*/);
  //
  svl_Except;
  svl::TString value;
  TStyle *style;
public:
  void GetSelectionText( svl::TString &str );
  bool EraseSelectionText();
  void InsertInCaretPos( svl::TString &str );
  void UpdateSelected( int oldPos, grf::TKeyboardKey &KeyboardKey );
  void ReupdateSelecting();
  void Copy();
  void Paste();
  void Cut();
};

///////////////////////////////////////////////////////////////////////////////
}}

#endif
